<?php
// +----------------------------------------------------------------------
// | 仓储框架 [ YHLaravel ]
// +----------------------------------------------------------------------
// | 版权所有 2018~2019 云恒信息科技
// +----------------------------------------------------------------------
// | 官方网站: http://www.yunhengwang.com
// +----------------------------------------------------------------------
// | Author: 相约在冬季 <zongjinlong@yunhengwang.com>
// +----------------------------------------------------------------------

namespace App\Http\Requests;

use Illuminate\Support\Facades\Request;

/**
 * 验证基类抽象类
 * @author zongjl
 * @date 2019/5/28
 * Class BaseRequest
 * @package App\Http\Requests
 */
abstract class BaseRequest extends AbstractRequest
{
    // 当前验证的规则
    protected $rule = [];

    // 验证提示信息
    protected $message = [];

    // 验证字段描述
    protected $field = [];

    // 验证场景 scene = ['edit'=>'name1,name2,...']
    protected $scene = [];

    /**
     * 表单验证【备注：场景验证后期实现】
     * @param array $data 验证数据源
     * @param array $rules 验证规则
     * @param string $scene 验证场景
     * @return bool 返回结果true或false
     * @author zongjl
     * @date 2019/5/28
     */
    public function check($data = [], $rules = [], $scene = '')
    {
        if (empty($rules)) {
            // 读取验证规则
            if (method_exists($this, 'rule')) {
                // 获取函数式验证规则
                $this->rule = $this->rule();
            } else {
                // 获取属性验证规则
                // TODO...
            }
        } else {
            // 外部自定义验证
            $this->rule = $rules;
        }

        // 获取场景验证规则
        $rules = $this->getRules($scene);
        // 获取场景验证提示语
        $message = $this->getMessage($rules);
        $validator = \Validator::make($data, $rules, $message);
        if ($validator->fails()) {
            // 显示所有错误提示语
            $errors = $validator->errors()->getMessages();
            // 显示所有提示语
            $message = $validator->messages();
            // 显示所有错误
            $all = $validator->errors()->all();
            // 显示第一条错误
            $error = $validator->errors()->first();

            $this->error = $error;

            return false;
        }
        return true;
    }

    /**
     * 获取场景验证规则
     * @param string $scene 验证场景
     * @return array 返回验证场景
     * @author zongjl
     * @date 2019/6/18
     */
    public function getRules($scene = '')
    {
        // 分析场景验证规则字段形式
        if (!empty($scene) && isset($this->scene[$scene])) {
            // 如果设置了验证适用场景
            $scene = $this->scene[$scene];
            if (is_string($scene)) {
                $scene = explode(',', $scene);
            }
        } else {
            $scene = [];
        }

        // 分析场景验证规则
        $rules = [];
        if ($scene) {
            foreach ($scene as $field) {
                if (array_key_exists($field, $this->rule)) {
                    $rules[$field] = $this->rule[$field];
                }
            }
        } else {
            // 不设置场景验证时,默认采用所有规则验证
            $rules = $this->rule;
        }
        return $rules;
    }

    /**
     * 获取场景验证提示信息
     * @param array $rules 场景验证规则
     * @return array 返回场景验证提示语
     * @author zongjl
     * @date 2019/6/18
     */
    public function getMessage($rules)
    {
        $message = [];
        foreach ($rules as $key => $v) {
            $item = [];
            if (is_string($v)) {
                $item = explode('|', $v);
            } elseif (is_array($v)) {
                foreach ($v as $vt) {
                    // 过滤自定义函数验证
                    if (is_object($vt)) {
                        continue;
                    }
                    if (strpos($vt, '|')) {
                        $args = explode('|', $vt);
                        $item = array_merge($item, $args);
                    } else {
                        $item[] = $vt;
                    }
                }
            }

            // 分解验证规则
            foreach ($item as $k => $val) {
                if (strpos($val, ':')) {
                    unset($item[$k]);
                    $item[] = substr($val, 0, strpos($val, ':'));
                }
            }

            // 重组验证提示信息
            foreach ($item as $value) {
                if (array_key_exists($key . '.' . $value, $this->message)) {
                    $message[$key . '.' . $value] = $this->message[$key . '.' . $value];
                }
            }
        }
        return $message;
    }
}
